/**
 * Created by IntelliJ IDEA.
 * User: Administrator
 * Date: Dec 31, 2009
 * Time: 10:39:01 AM
 * To change this template use File | Settings | File Templates.
 */
import java.util.*;
import org.jdom.Element;

// Referenced classes of package dk.brics.dsd:
//            MemoKey, InternalSchemaErrorException, AndBoolexp, OrBoolexp,
//            NotBoolexp, ImplyBoolexp, EquivBoolexp, OneBoolexp,
//            ParentBoolexp, AncestorBoolexp, ChildBoolexp, DescendantBoolexp,
//            ThisBoolexp, ElementBoolexp, AttributeBoolexp, ContentsBoolexp,
//            ReferenceBoolexp, Schema, Context

abstract class Boolexp
{

    Boolexp()
    {
    }

    static void resetMemo()
    {
        memo = new HashMap();
    }

    byte evaluateMemo(Context context)
    {
        MemoKey memokey = new MemoKey(this, context);
        if(memo.containsKey(memokey))
        {
            byte byte0 = ((Byte)memo.get(memokey)).byteValue();
            if(byte0 == 0)
                return 2;
            else
                return byte0;
        } else
        {
            memo.put(memokey, new Byte((byte)0));
            byte byte1 = evaluate(context);
            memo.put(memokey, new Byte(byte1));
            return byte1;
        }
    }

    abstract byte evaluate(Context context);

    abstract boolean isMentioned(Context context);

    abstract Element toXML(Context context);

    static List parseList(Element element, Schema schema)
    {
        ArrayList arraylist = new ArrayList();
        Iterator iterator = element.getChildren().iterator();
        do
        {
            if(!iterator.hasNext())
                break;
            Element element1 = (Element)iterator.next();
            if(Schema.isDSDElement(element1))
                arraylist.add(parse(element1, schema));
        } while(true);
        return arraylist;
    }

    static Boolexp parseOne(Element element, Schema schema)
    {
        Boolexp boolexp = parseOneOptional(element, schema);
        if(boolexp == null)
            throw new InternalSchemaErrorException();
        else
            return boolexp;
    }

    static Boolexp parseOneOptional(Element element, Schema schema)
    {
        for(Iterator iterator = element.getChildren().iterator(); iterator.hasNext();)
        {
            Element element1 = (Element)iterator.next();
            if(Schema.isDSDElement(element1))
                return parse(element1, schema);
        }

        return null;
    }

    static Boolexp parse(Element element, Schema schema)
    {
        String s = element.getName();
        Object obj;
        if(s.equals("and"))
            obj = new AndBoolexp(element, schema);
        else
        if(s.equals("or"))
            obj = new OrBoolexp(element, schema);
        else
        if(s.equals("not"))
            obj = new NotBoolexp(element, schema);
        else
        if(s.equals("imply"))
            obj = new ImplyBoolexp(element, schema);
        else
        if(s.equals("equiv"))
            obj = new EquivBoolexp(element, schema);
        else
        if(s.equals("one"))
            obj = new OneBoolexp(element, schema);
        else
        if(s.equals("parent"))
            obj = new ParentBoolexp(element, schema);
        else
        if(s.equals("ancestor"))
            obj = new AncestorBoolexp(element, schema);
        else
        if(s.equals("child"))
            obj = new ChildBoolexp(element, schema);
        else
        if(s.equals("descendant"))
            obj = new DescendantBoolexp(element, schema);
        else
        if(s.equals("this"))
            obj = new ThisBoolexp(element, schema);
        else
        if(s.equals("element"))
            obj = new ElementBoolexp(element, schema);
        else
        if(s.equals("attribute"))
            obj = new AttributeBoolexp(element, schema);
        else
        if(s.equals("contents"))
            obj = new ContentsBoolexp(element, schema);
        else
        if(s.equals("boolexp"))
            obj = new ReferenceBoolexp(element, schema);
        else
            throw new InternalSchemaErrorException(s);
        return ((Boolexp) (obj));
    }

    boolean containsThis(Context context)
    {
        return false;
    }

    static final byte BOTTOM = 0;
    static final byte TRUE = 1;
    static final byte FALSE = 2;
    static final byte SOME = 3;
    static final byte DONTKNOW = 4;
    static Map memo;
}
